package com.mijie.homi.common.protocol;

import java.nio.charset.Charset;

import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

import com.mijie.homi.common.constant.HomiConstants;
import com.mijie.homi.common.constant.TypeCode;



public class HomiProtocolEncoder extends ProtocolEncoderAdapter {

	private Charset charset;
	
	public HomiProtocolEncoder(Charset charset){
		this.charset = charset;
	}
	
	public void encode(IoSession session, Object message,
			ProtocolEncoderOutput out) throws Exception {
		HomiProtocol protocol = (HomiProtocol) message; 
		
		IoBuffer buff = null;
		if(protocol.getType()>TypeCode.MESSAGE_ROUTER_REPORT){
			buff = wrapMessageRouterBuffer(protocol);
		}else{
			buff = wrapGeneralMessageBuffer(protocol);
		}
		
        out.write(buff); 
	}
	
	private IoBuffer wrapGeneralMessageBuffer(HomiProtocol protocol){
		byte[] content = null;
		int contentLen = 0;
		
		if(protocol.getContent()!=null){
			content = protocol.getContent().getBytes(charset);
			contentLen = content.length;
		}
		
		int length = contentLen + HomiConstants.PROTOCOL_TYPE_LENGTH;
        IoBuffer buff = IoBuffer.allocate(length+HomiConstants.PROTOCOL_HEAD_LENGTH);
        buff.setAutoExpand(true);
        buff.putInt(length); 
        buff.putShort(protocol.getType());
        if(content!=null)
        	buff.put(content); 
        buff.flip(); 
        return buff;
	}
	
	private IoBuffer wrapMessageRouterBuffer(HomiProtocol protocol){
		if(protocol.getId()==null || protocol.getId().trim().isEmpty())
			throw new NullPointerException("MessageRouter protocol must have id.");
		
		byte[] content = null;
		int contentLen = 0;
		if(protocol.getContent()!=null){
			content = protocol.getContent().getBytes(charset);
			contentLen = content.length;
		}
		byte[] id = protocol.getId().getBytes(charset);
		int length = contentLen + id.length + HomiConstants.PROTOCOL_ID_LENGTH  + HomiConstants.PROTOCOL_CONTENT_LENGTH + HomiConstants.PROTOCOL_TYPE_LENGTH;
		
        IoBuffer buff = IoBuffer.allocate(length+HomiConstants.PROTOCOL_HEAD_LENGTH);
        buff.setAutoExpand(true);
        buff.putInt(length); 
        buff.putShort(protocol.getType());
        buff.putInt(id.length);
        buff.put(id);
        buff.putInt(contentLen);
        if(content!=null)
        	buff.put(content); 
        buff.flip(); 
        return buff;
	}
}
